package com.xunwulian.cmpp.client.handler;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import com.xunwulian.base.constant.ConstantBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 动态暴露服务，可以指定group，版本号等
 * @param <T>
 */
public class Provider<T> {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final String DUBBO_PROTOCOL = "dubbo";
    private static final String SERVICE_VERSION = "0.0.1";

    public Provider(T api, Class<?> iface, String group, String appId, String registryAddress, Integer port) {

        checkNotNull(group, "group can not be null");

        // 当前应用配置
        ApplicationConfig application = new ApplicationConfig();
        application.setName("provider-" + api.getClass().getSimpleName() + "-" +  appId);

        // 注意：ServiceConfig为重对象，内部封装了与注册中心的连接，以及开启服务端口

        // 服务提供者暴露服务配置
        ServiceConfig<T> service = new ServiceConfig<>(); // 此实例很重，封装了与注册中心的连接，请自行缓存，否则可能造成内存和连接泄漏
        service.setApplication(application);

        // 连接注册中心配置
        List<RegistryConfig> registryConfigList = new ArrayList();
        Arrays.stream(registryAddress.split(ConstantBean.REGISTER_SPLITTER)).forEach(p -> {
            RegistryConfig registry = new RegistryConfig();
            registry.setAddress(registryAddress);
            registryConfigList.add(registry);
        });

        // TODO 支持多个注册中心 多个注册中心可以用setRegistries()
        service.setRegistries(registryConfigList);

        // 服务提供者协议配置
        ProtocolConfig protocol = new ProtocolConfig();
        protocol.setName(DUBBO_PROTOCOL);
        protocol.setPort(port);

        // 多个协议可以用setProtocols()
        service.setProtocol(protocol);
        service.setGroup(group);
        service.setInterface(iface);
        service.setRef(api);
//        service.setVersion(SERVICE_VERSION);

        // 暴露及注册服务
        service.export();
    }
}
